﻿using CommunityToolkit.Mvvm.ComponentModel;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using static System.Windows.Forms.VisualStyles.VisualStyleElement.Rebar;

namespace HardToolApp.Model
{
    internal class UpdateModel : Peripheral
    {
        public enum SubCmd
        {
            Begin = 1,
            Send,
            Stop,
            Version
        };
        int perPkgNum = 32;
        public UInt16 _pkgAll;
        public UInt16 _pkgNow;
        public UInt16 pkgAll { get { return _pkgAll; } set { SetProperty(ref _pkgAll, value); } }
        public UInt16 pkgNow { get { return _pkgNow; } set { SetProperty(ref _pkgNow, value); } }
        public byte[] sendByte;

        string _fileVersion;
        public string Version { get { return _fileVersion; } set { SetProperty(ref _fileVersion, value); } }
        public string UpVersion { get { return GetUpVersion(); } }

        public UpdateModel():base(CommCmd.COMM_UPDATE)
        {
            Assembly assembly = Assembly.GetExecutingAssembly();
            string resourceName = assembly.GetName().Name.ToString() + ".firmware.HardTools.bin";
            using (Stream stream = assembly.GetManifestResourceStream(resourceName))
            {
                pkgAll = (UInt16)((stream.Length / perPkgNum) + (stream.Length % perPkgNum > 0 ? 1 : 0));
                sendByte = new byte[stream.Length];
                stream.Seek(0, SeekOrigin.Begin);
                stream.Read(sendByte, 0, sendByte.Length);
            }
        }

        public byte[] GetBytes(int num)
        {
            pkgNow = (UInt16)num;
            return GetBytes();
        }
        public byte[] GetBytes()
        {
            int thisLen = perPkgNum;
            if(sendByte.Length - pkgNow * perPkgNum < perPkgNum)
            {
                thisLen = (int)(sendByte.Length - pkgNow * perPkgNum);
            }
            byte[] buffer = new byte[thisLen];
            for(int i = 0 ; i < thisLen; i++)
            {
                buffer[i] = sendByte[i + pkgNow * perPkgNum];
            }
            return buffer;
        }
         string GetUpVersion()
        {
            int VersionAddr = 0x800FC00 - 0x8004000;
            Assembly assembly = Assembly.GetExecutingAssembly();
            string resourceName = assembly.GetName().Name.ToString() + ".firmware.HardTools.bin";
            using (Stream stream = assembly.GetManifestResourceStream(resourceName))
            {
                byte[] buffer = new byte[4];
                stream.Seek(VersionAddr, SeekOrigin.Begin);
                stream.Read(buffer, 0, buffer.Length);
                return VerStr(buffer[3], buffer[2], buffer[1], buffer[0]);      
            }
        }

        public static string VerStr(ulong t)
        {
            byte b1 = (byte)(t >> 24 & 0xff);
            byte b2 = (byte)(t >> 16 & 0xff);
            byte b3 = (byte)(t >> 8 & 0xff);
            byte b4 = (byte)(t & 0xff);
            return "V" + b1.ToString() + "." + b2.ToString() + "." + b3.ToString() + "." + b4.ToString();
        }

        public static string VerStr(byte b1, byte b2, byte b3, byte b4)
        {
            return "V" + b1.ToString() + "." + b2.ToString() + "." + b3.ToString() + "." + b4.ToString();
        }

    }
}
